// user-module/src/main/java/org/x/user/service/impl/SysConfigServiceImpl.java
package org.x.user.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.x.user.entity.SysConfigEntity;
import org.x.user.entity.SysConfigHistoryEntity;
import org.x.user.entity.SysUserEntity;
import org.x.user.mapper.SysConfigHistoryMapper;
import org.x.user.mapper.SysConfigMapper;
import org.x.user.mapper.SysUserMapper;
import org.x.user.service.ISysConfigService;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 系统配置表 服务层实现。
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class SysConfigServiceImpl extends ServiceImpl<SysConfigMapper, SysConfigEntity> implements ISysConfigService {

    private static final Logger logger = LoggerFactory.getLogger(SysConfigServiceImpl.class);

    private final Map<String, String> configCache = new ConcurrentHashMap<>();
    private volatile boolean cacheLoaded = false;
    private volatile long lastCheckTime = System.currentTimeMillis();

    @Autowired
    private SysConfigHistoryMapper sysConfigHistoryMapper;

    @Autowired
    private SysConfigMapper sysConfigMapper;

    @Autowired
    private SysUserMapper sysUserMapper;


    @Override
    public boolean validateConfigValue(String configKey, String configValue) {
        // 示例：允许所有配置值通过验证，可根据实际业务增加校验逻辑
        logger.info("校验配置项: key={}, value={}", configKey, configValue);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateConfigValue(Integer id, String configValue) {
        logger.info("准备更新配置项，ID: {}, 新值: {}", id, configValue);

        try {
            // 获取当前配置项信息
            SysConfigEntity currentEntity = sysConfigMapper.selectOneById(id);
            if (currentEntity == null) {
                logger.error("配置项不存在，ID: {}", id);
                return false;
            }

            // 记录变更历史
            SysConfigHistoryEntity history = new SysConfigHistoryEntity();
            history.setConfigId(Long.valueOf(id));
            history.setConfigKey(currentEntity.getConfigKey());
            history.setOldValue(currentEntity.getConfigValue());
            history.setNewValue(configValue);
            history.setOperatorId(getCurrentUserId());
            history.setOperatorName(getCurrentUserName());
            history.setCreatedTime(new Date());
            sysConfigHistoryMapper.insert(history);

            // 使用 updateByQuery 替代 update
            SysConfigEntity entity = new SysConfigEntity();
            // 对敏感配置进行加密
            //entity.setConfigValue(encryptConfigValue(currentEntity.getConfigKey(), configValue));
            entity.setConfigValue(configValue);
            entity.setUpdatedTime(new Date()); // 设置更新时间

            QueryWrapper queryWrapper = new QueryWrapper()
                    .eq("id", id);
            int rowsAffected = sysConfigMapper.updateByQuery(entity, queryWrapper);

            boolean result = rowsAffected > 0;

            logger.info("配置项更新结果: {}, ID: {}, 新值: {}, 影响行数: {}", result, id, configValue, rowsAffected);
            if (result) {
                SysConfigEntity updatedEntity = sysConfigMapper.selectOneById(id);
                logger.info("更新后的配置项: ID={}, configKey={}, configValue={}, updatedTime={}",
                        updatedEntity.getId(), updatedEntity.getConfigKey(),
                        updatedEntity.getConfigValue(), updatedEntity.getUpdatedTime());

                // 刷新缓存
                refreshCacheInternal();
            }

            return result;

        } catch (Exception e) {
            logger.error("更新配置项失败，ID: {}, 新值: {}", id, configValue, e);
            return false;
        }
    }


    @Scheduled(fixedRate = 300000) // 每5分钟检查一次
    public void checkConfigUpdates() {
        try {
            Long lastUpdate = getLastUpdateTime();
            if (lastUpdate != null && lastUpdate > lastCheckTime) {
                refreshCacheInternal();
                lastCheckTime = System.currentTimeMillis();
                logger.info("检测到配置更新，已刷新缓存");
            }
        } catch (Exception e) {
            logger.error("检查配置更新时发生错误", e);
        }
    }

    public Long getLastUpdateTime() {
        try {
            QueryWrapper queryWrapper = new QueryWrapper()
                    .select("MAX(updated_time) as last_update")
                    .from("sys_config");

            Map<String, Object> result = sysConfigMapper.selectOneByQueryAs(queryWrapper, Map.class);
            if (result != null) {
                Object lastUpdateObj = result.get("last_update");
                if (lastUpdateObj instanceof Date) {
                    return ((Date) lastUpdateObj).getTime();
                }
            }
        } catch (Exception e) {
            logger.error("获取最后更新时间失败", e);
        }
        return null;
    }

    private void refreshCacheInternal() {
        logger.info("开始刷新系统配置缓存");

        try {
            // 清除现有缓存
            configCache.clear();

            // 重新加载所有配置项
            List<SysConfigEntity> configList = this.list();

            // 将配置项存入缓存
            for (SysConfigEntity config : configList) {
                configCache.put(config.getConfigKey(), config.getConfigValue());
            }

            // 标记缓存已加载
            cacheLoaded = true;

            logger.info("系统配置缓存刷新完成，共加载 {} 条配置", configList.size());
        } catch (Exception e) {
            logger.error("刷新系统配置缓存失败", e);
        }
    }

    @Override
    public Map<String, Object> refreshCache() {
        refreshCacheInternal();

        // 返回重载的配置项数量
        Map<String, Object> result = new HashMap<>();
        result.put("reloadedCount", configCache.size());
        return result;
    }


    // 修改获取公共配置的方法，使其支持环境隔离
    @Override
    public List<SysConfigEntity> getPublicConfigs() {
        // 从上下文或配置中获取当前环境，这里简化处理，默认使用prod环境
        String currentEnv = getCurrentEnv();

        logger.info("获取环境 {} 的公共配置项", currentEnv);

        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("env", currentEnv);

        List<SysConfigEntity> allConfigs = sysConfigMapper.selectListByQuery(queryWrapper);

        // 过滤出公共配置项
        List<SysConfigEntity> publicConfigs = allConfigs.stream()
                .filter(config -> isPublicConfig(config.getConfigKey()))
                .collect(Collectors.toList());

        logger.info("获取到 {} 条公共配置项", publicConfigs.size());

        return publicConfigs;
    }

    // 辅助方法：获取当前环境
    private String getCurrentEnv() {
        // 可以从系统属性、环境变量或配置文件中获取
        // 示例：从系统属性获取
        String env = System.getProperty("app.env");
        if (env == null || env.isEmpty()) {
            env = "prod"; // 默认环境
        }
        return env;
    }

    // 修改创建配置的方法，添加环境信息
    @Override
    public boolean createConfigWithValidation(SysConfigEntity config) {
        // 如果未设置环境，则使用默认环境
        if (config.getEnv() == null || config.getEnv().isEmpty()) {
            config.setEnv("prod");
        }

        // 验证配置键命名规则
        if (!config.getConfigKey().matches("^[a-z_]+$")) {
            throw new RuntimeException("配置键必须由小写字母和下划线组成");
        }

        // 验证配置键唯一性（在同一环境中）
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("config_key", config.getConfigKey());
        queryWrapper.eq("env", config.getEnv());

        if (sysConfigMapper.selectCountByQuery(queryWrapper) > 0) {
            throw new RuntimeException("配置键在当前环境中必须唯一");
        }

        config.setCreatedTime(new Date());
        config.setUpdatedTime(new Date());
        // 暂时不进行加密处理
        // config.setConfigValue(encryptConfigValue(config.getConfigKey(), config.getConfigValue()));

        boolean result = sysConfigMapper.insert(config) > 0;

        if (result) {
            // 刷新缓存
            refreshCacheInternal();
        }

        return result;
    }

    @Override
    public Map<String, Object> getPublicConfigMap() {
        List<SysConfigEntity> publicConfigs = getPublicConfigs();
        Map<String, Object> configMap = new HashMap<>();

        for (SysConfigEntity config : publicConfigs) {
            String key = config.getConfigKey();
            String value = config.getConfigValue();
            configMap.put(key, convertValue(key, value));
        }

        return configMap;
    }

    @Override
    public Map<String, Object> getPublicConfigsForFrontend() {
        Map<String, Object> publicConfigs = getPublicConfigMap();

        // 转换为前端需要的格式
        Map<String, Object> resultConfigs = new HashMap<>();
        for (Map.Entry<String, Object> entry : publicConfigs.entrySet()) {
            // 根据配置键名转换为前端需要的字段名
            switch (entry.getKey()) {
                case "site_name":
                    resultConfigs.put("siteName", entry.getValue());
                    break;
                case "consult_fee":
                    resultConfigs.put("consultFee", entry.getValue());
                    break;
                case "case_timeout":
                    resultConfigs.put("caseTimeout", entry.getValue());
                    break;
                case "copyright":
                    resultConfigs.put("copyright", entry.getValue());
                    break;
                default:
                    resultConfigs.put(entry.getKey(), entry.getValue());
                    break;
            }
        }

        return resultConfigs;
    }

    @Override
    public List<SysConfigHistoryEntity> getConfigHistory(String configKey, Long operatorId, Date startTime, Date endTime) {
        QueryWrapper queryWrapper = new QueryWrapper();

        if (configKey != null && !configKey.isEmpty()) {
            queryWrapper.eq(SysConfigHistoryEntity::getConfigKey, configKey);
        }

        if (operatorId != null) {
            queryWrapper.eq(SysConfigHistoryEntity::getOperatorId, operatorId);
        }

        if (startTime != null) {
            queryWrapper.ge(SysConfigHistoryEntity::getCreatedTime, startTime);
        }

        if (endTime != null) {
            queryWrapper.le(SysConfigHistoryEntity::getCreatedTime, endTime);
        }

        queryWrapper.orderBy(SysConfigHistoryEntity::getCreatedTime, false);

        return sysConfigHistoryMapper.selectListByQuery(queryWrapper);
    }



    private Long getCurrentUserId() {
        // 从安全上下文中获取当前用户ID
        try {
            return StpUtil.getLoginIdAsLong();
        } catch (Exception e) {
            // 如果无法获取当前用户，则返回默认值
            logger.warn("无法获取当前用户ID，使用默认值1L", e);
            return 1L;
        }
    }
    private String getCurrentUserName() {
        // 从安全上下文中获取当前用户名
        try {
            // 获取当前用户ID
            Long userId = StpUtil.getLoginIdAsLong();

            // 根据用户ID查询用户信息
            SysUserEntity user = sysUserMapper.selectOneById(userId);
            if (user != null && user.getUsername() != null) {
                return user.getUsername();
            }
            // 如果无法获取用户名，则返回默认值
            return "system";
        } catch (Exception e) {
            logger.warn("无法获取当前用户名，使用默认值system", e);
            return "system";
        }
    }

    private boolean isPublicConfig(String configKey) {
        // 定义公共配置键的集合
        Set<String> publicKeys = Set.of("site_name", "consult_fee", "case_timeout", "copyright");
        return publicKeys.contains(configKey);
    }

    private Object convertValue(String key, String value) {
        switch (key) {
            case "consult_fee":
            case "case_timeout":
                try {
                    return Integer.parseInt(value);
                } catch (NumberFormatException e) {
                    return value; // 如果转换失败，返回原始值
                }
            default:
                return value;
        }
    }
}
